// #pragma once

// #include <iostream>
// #include <string>
// #include <cstring>
// #include <pthread.h>
// #include <functional>
// #include <cassert>
// #include <memory>
// #include <unistd.h>
// // header only 开源代码

// class Thread;

// class Context
// {
// public:
//     Thread *_this;
//     void *_args;

//     Context():_this(nullptr),_args(nullptr)
//     {

//     }

//     ~Context()
//     {

//     }
// };



// //template<class T>
// class Thread
// {
// public:
//     //using func_t = std::function<void*(void*)>;
//     typedef std::function<void*(void*)> func_t;
//     //typedef void* (*func_t)(void*);
//     const int num = 1024;

// public:
//     Thread(func_t func,void* args, int number):_func(func),_args(args)
//     {
//         //_name = "thread-";
//         //_name += std::to_string(number);

//         char buffer[num];
//         snprintf(buffer,sizeof buffer,"thread-%d",number);
//         _name = buffer;
//     }

//     static void* start_roution(void* args)
//     {
//         Context *ctx = static_cast<Context *>(args);
//         void* ret = ctx->_this->run(ctx->_args);
//         delete ctx;
//         return ret;
//     }

//     void start()
//     {
//         Context *ctx = new Context();
//         ctx->_this = this;
//         ctx->_args = this->_args;
//         int n = pthread_create(&_tid,nullptr,start_roution,ctx);
//         assert(n == 0);
//         (void)n;
//     }

//     void join()
//     {
//         int n = pthread_join(_tid,nullptr);
//         assert(n == 0);
//         (void)n;
//     }

//     void* run(void* args)
//     {
//         return _func(args);
//     }

//     ~Thread()
//     {

//     }

// private:
//     func_t _func;
//     std::string _name;
//     void* _args;
//     pthread_t _tid;
// };



#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <pthread.h>
#include <functional>
#include <cassert>
#include <memory>
#include <unistd.h>
// header only 开源代码

class Thread;

class Context
{
public:
    Thread *_this;
    void *_args;

    Context():_this(nullptr),_args(nullptr)
    {

    }

    ~Context()
    {

    }
};



//template<class T>
class Thread
{
public:
    //using func_t = std::function<void*(void*)>;
    typedef std::function<void*(void*)> func_t;
    //typedef void* (*func_t)(void*);
    const int num = 1024;

public:
    Thread(func_t func,void* args = nullptr, int number = 0):_func(func),_args(args)
    {
        //_name = "thread-";
        //_name += std::to_string(number);

        char buffer[num];
        snprintf(buffer,sizeof buffer,"thread-%d",number);
        _name = buffer;

        Context *ctx = new Context();
        ctx->_this = this;
        ctx->_args = this->_args;
        int n = pthread_create(&_tid,nullptr,start_roution,ctx);
        assert(n == 0);
        (void)n;

    }

    static void* start_roution(void* args)
    {
        Context *ctx = static_cast<Context *>(args);
        void* ret = ctx->_this->run(ctx->_args);
        delete ctx;
        return ret;
    }

    void join()
    {
        int n = pthread_join(_tid,nullptr);
        assert(n == 0);
        (void)n;
    }

    void* run(void* args)
    {
        return _func(args);
    }

    ~Thread()
    {

    }

private:
    func_t _func;
    std::string _name;
    void* _args;
    pthread_t _tid;
};

